package com.example.demo.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@Component
@Aspect // 切面
public class NoRepeatSubmitAspect {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    // 切点
    @Pointcut("@annotation(noRepeatSubmit)")
    public void pointCut(NoRepeatSubmit noRepeatSubmit) {
    }

    // 环绕通知
    @Around("pointCut(noRepeatSubmit)")
    public Object around(ProceedingJoinPoint joinPoint, NoRepeatSubmit noRepeatSubmit) throws Throwable {
        // 防止重复提交时间
        int lockSeconds = noRepeatSubmit.lockTime();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 得到 sessionId
        String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
        // 得到请求的 url
        String path = request.getServletPath();
        // 使用 sessionId + 访问 url = redis 中的 key
        String key = sessionId + "-" + path;
        if (stringRedisTemplate.opsForValue().get(key) == null) { // 未访问过此 url（一段时间内）
            // 执行目标方法
            Object result = joinPoint.proceed();
            stringRedisTemplate.opsForValue().set(key, String.valueOf(0),
                    lockSeconds, TimeUnit.SECONDS);
            return result;
        } else {
            return "重复请求，请稍后再试！";
        }
    }
}
